package com.eastfair.certificate.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.annotation.annotation.base.BaseControllerInfo;
import com.eastfair.annotation.annotation.log.SysLog;
import com.eastfair.annotation.annotation.tenant.TenantAuth;
import com.eastfair.certificate.dto.*;
import com.eastfair.certificate.entity.Certificate;
import com.eastfair.certificate.entity.CertificateOrder;
import com.eastfair.certificate.entity.CertificateUser;
import com.eastfair.certificate.enumeration.*;
import com.eastfair.certificate.exceptioncode.CertificateExceptionCode;
import com.eastfair.certificate.service.CertificateOrderService;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.eastfair.boot.controller.SuperController;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.eastfair.certificate.service.CertificateService;
import com.eastfair.certificate.service.CertificateUserService;
import com.eastfair.certificate.vo.*;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.context.ContextConstants;
import com.eastfair.core.exception.BizException;
import com.eastfair.core.exception.NoBackBizException;
import com.eastfair.demand.certificate.CertificateOrderGroup;
import com.eastfair.demand.certificate.CertificateUserGroup;
import com.eastfair.echo.core.EchoService;
import com.eastfair.core.base.R;
import com.eastfair.venuebooking.api.ServiceProviderFeign;
import com.eastfair.venueservice.dto.ServiceProviderDTO;
import com.eastfair.venueservice.vo.ServiceProviderVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.eastfair.annotation.annotation.security.PreAuth;

import com.eastfair.boot.request.PageParams;
import com.eastfair.core.context.ContextUtil;

import javax.annotation.Resource;


/**
 * <p>
 * 前端控制器
 * 制证订单
 * </p>
 *
 * @author ligang
 * @date 2022-08-02
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/certificateOrder")
@Api(value = "CertificateOrder", tags = "制证订单")
@PreAuth(replace = "certificate:certificateOrder:")
public class CertificateOrderController extends SuperController<CertificateOrderService, Long, CertificateOrder, CertificateOrderPageQuery, CertificateOrderSaveDTO, CertificateOrderUpdateDTO> {

    @Autowired
    private EchoService echoService;

    @Autowired
    CertificateUserService certificateUserService;

    @Autowired
    CertificateService certificateService;
    @Resource
    private ServiceProviderFeign serviceProviderFeign;

    @Override
    public void handlerResult(IPage<CertificateOrder> page) {
        // 想让返回值实现自动回显，请将此行代码打开
        // echoService.action(page);
    }

    /**
     * Excel导入后的操作
     *
     * @param list
     */
    @Override
    public R<Boolean> handlerImport(List<Map<String, String>> list) {
        List<CertificateOrder> certificateOrderList = list.stream().map((map) -> {
            CertificateOrder certificateOrder = CertificateOrder.builder().build();
            //TODO 请在这里完成转换
            return certificateOrder;
        }).collect(Collectors.toList());

        return R.success(baseService.saveBatch(certificateOrderList));
    }


    /**
     * 处理参数
     *
     * @param params 分页参数
     */
    @Override
    public void handlerQueryParams(PageParams<CertificateOrderPageQuery> params) {
        CertificateOrderPageQuery pageQuery = params.getModel();
        //分页处理
        if (ContextUtil.getProjectId() != null) {
            pageQuery.setProjectId(ContextUtil.getProjectId());
        }
    }

    /**
     * 生成订单
     *
     * @param certificateOrderDTO 用户证件id集合
     * @return
     */
    @PostMapping("/createOrder")
    @ApiOperation(value = "生成订单")
    @SysLog("生成订单")
    @BaseControllerInfo(voGroup = CertificateOrderGroup.pageOrder.class)
    public R createOrder(@RequestBody @Validated({CertificateOrderDTO.createOrder.class}) CertificateOrderDTO certificateOrderDTO) {
        //拆分公司分组
        List<CertificateOrderVO> certificateOrderVOList = new ArrayList<>();

        List<CertificateUser> certificateUserList = certificateUserService.list(null, certificateOrderDTO.getCertificateUserIdList());
        if (certificateUserList == null || certificateUserList.isEmpty()) {
            throw BizException.wrap(CertificateExceptionCode.CERTIFICATE_NULL);
        }
        for (CertificateUser certificateUser : certificateUserList) {
            if (ContextUtil.getTeamId() == null) {
                if (certificateUser.getTeamId() != null) {
                    throw BizException.wrap(CertificateExceptionCode.CERTIFICATE_TEAM);
                }
            }
        }
        Map<Long, List<CertificateUser>> listMap = certificateUserList.stream().collect(Collectors.groupingBy(CertificateUser::getCompanyId));
        for (List<CertificateUser> certificateUserList1 : listMap.values()) {
            CertificateOrderVO certificateOrderVO = baseService.createOrder(certificateUserList1.stream().map(CertificateUser::getId).collect(Collectors.toList()));
            //记录订单号
            for(CertificateUser certificateUser : certificateUserList1){
                certificateUser.setOrderNumber(certificateOrderVO.getOrderNumber());
                certificateUserService.updateById(certificateUser);
            }
            certificateOrderVOList.add(certificateOrderVO);
        }
        return R.success(certificateOrderVOList);
    }


    /**
     * 删除订单关系
     *
     * @param certificateOrderDTO 用户证件id集合
     * @return
     */
    @PostMapping("/removeOrder")
    @ApiOperation(value = "删除订单关系")
    public R<CertificateOrderVO> removeOrder(@RequestBody @Validated({CertificateOrderDTO.createOrder.class}) CertificateOrderDTO certificateOrderDTO) {
        return R.success(baseService.removeOrder(certificateOrderDTO.getCertificateUserIdList()));
    }

    /**
     * 分页查询订单
     *
     * @param params
     * @return
     */
    @PostMapping("/pageOrder")
    @ApiOperation(value = "分页查询订单")
    @TenantAuth()
    @BaseControllerInfo(voGroup = CertificateOrderGroup.pageOrder.class)
    public R<IPage<CertificateOrderVO>> pageOrder(@RequestBody PageParams<CertificateOrderDTO> params) {
        return R.success(baseService.pageOrder(params));
    }


    /**
     * 预支付订单
     *
     * @param certificateOrderDTO
     * @return
     */
    @PostMapping("/readyPayOrder")
    @ApiOperation(value = "预支付订单")
    @SysLog("预支付订单")
    public R readyPayOrder(@RequestBody CertificateOrderDTO certificateOrderDTO) {
        List<CertificateOrder> certificateOrderList = baseService.list(certificateOrderDTO, null);
        if (CollectionUtil.isNotEmpty(certificateOrderList)) {
            CertificateOrder certificateOrder = certificateOrderList.get(0);
            certificateOrder.setOrderStatus(CertificateOrderOrderStatusEnum.WAIT);
            baseService.updateById(certificateOrder);
            return R.success();
        }
        return R.fail("支付失败");
    }


    /**
     * 支付订单
     *
     * @param certificateOrderDTO
     * @return
     */
    @PostMapping("/payOrder")
    @ApiOperation(value = "支付订单")
    @SysLog("支付订单")
    public R<CertificateOrderVO> payOrder(@RequestBody CertificateOrderDTO certificateOrderDTO) {
        if(certificateOrderDTO.getId()!=null){
            //走原来流程
            CertificateOrder certificateOrder = baseService.getByIdCache(certificateOrderDTO.getId());
            if(certificateOrder==null){
                throw NoBackBizException.wrap(CertificateExceptionCode.ORDER_NUll);
            }
            BigDecimal takeMoney = new BigDecimal(0);
            takeMoney = certificateOrder.getCostMoney()
                    .add(certificateOrder.getDepositMoney() == null ? new BigDecimal(0) : certificateOrder.getDepositMoney());
            certificateOrder.setOrderMoney(takeMoney);
            CertificateOrderVO certificateOrderVO = baseService.payOrder(certificateOrder);
            return R.success(certificateOrderVO);
        }else{
            //走真实支付流程
            CertificateOrderDTO queryCertificateOrderDTO = new CertificateOrderDTO();
            queryCertificateOrderDTO.setOrderNumber(certificateOrderDTO.getOrderNumber());
            List<CertificateOrder> certificateOrderList = baseService.list(queryCertificateOrderDTO, null);
            if (CollectionUtil.isNotEmpty(certificateOrderList)) {
                CertificateOrder certificateOrder = certificateOrderList.get(0);
                certificateOrder.setOrderMoney(certificateOrderDTO.getOrderMoney());
//            if(CertificateOrderOrderStatusEnum.WAIT.eq(certificateOrder.getOrderStatus())){
//                throw NoBackBizException.wrap(CertificateExceptionCode.ORDER_READY_PAY);
//            }
                CertificateOrderVO certificateOrderVO = baseService.payOrder(certificateOrder);
                return R.success(certificateOrderVO);
            } else {
                throw NoBackBizException.wrap(CertificateExceptionCode.ORDER_NUll);
            }
        }


    }

    /**
     * 取消订单
     *
     * @param certificateOrderDTO 订单id
     * @return
     */
    @PostMapping("/cancelOrder")
    @ApiOperation(value = "取消订单")
    @SysLog("取消订单")
    public R<CertificateOrderVO> cancelOrder(@RequestBody CertificateOrderDTO certificateOrderDTO) {
        return R.success(baseService.cancelOrder(certificateOrderDTO.getId()));
    }

    /**
     * 领取订单
     *
     * @param certificateOrderDTO 订单id
     * @return
     */
    @PostMapping("/drawOrder")
    @ApiOperation(value = "领取订单")
    @SysLog("领取订单")
    public R<CertificateOrderVO> drawOrder(@RequestBody CertificateOrderDTO certificateOrderDTO) {
        return R.success(baseService.drawOrder(certificateOrderDTO));
    }


    /**
     * 预约领取
     *
     * @param certificateOrderDTO 订单id
     * @return
     */
    @PostMapping("/makeDrawOrder")
    @ApiOperation(value = "预约领取")
    @SysLog("预约领取")
    public R<CertificateOrderVO> makeDrawOrder(@RequestBody CertificateOrderDTO certificateOrderDTO) {
        return R.success(baseService.makeDrawOrder(certificateOrderDTO));
    }


//    /**
//     * 订单开取发票
//     *
//     * @param certificateOrderDTO 订单id
//     * @return
//     */
//    @PostMapping("/takeOrder")
//    @ApiOperation(value = "订单开取发票")
//    public R<CertificateOrderVO> takeOrder(@RequestBody CertificateOrderDTO certificateOrderDTO) {
//        return R.success(baseService.takeOrder(certificateOrderDTO.getId()));
//    }


    /**
     * 退款金额
     *
     * @param orderId 订单id
     * @return
     */
    @GetMapping("/queryReturnMoney")
    @ApiOperation(value = "退款金额")
    @SysLog("查询退款金额")
    public R<BigDecimal> queryReturnMoney(Long orderId) {
        return R.success(baseService.queryReturnMoney(orderId));
    }

    /**
     * 发票金额
     *
     * @param orderId 订单id
     * @return
     */
    @GetMapping("/queryTakeMoney")
    @ApiOperation(value = "发票金额")
    @SysLog("查询发票金额")
    public R<BigDecimal> queryTakeMoney(Long orderId) {
        return R.success(baseService.queryTakeMoney(orderId));
    }

    /**
     * 证件申请退款
     *
     * @param certificateOrderDTO 订单id
     * @return
     */
    @PostMapping("/executeReturnOrder")
    @ApiOperation(value = "证件申请退款")
    @SysLog("证件申请退款")
    public R<CertificateOrderVO> executeReturnOrder(@RequestBody CertificateOrderDTO certificateOrderDTO) {
        return R.success(baseService.executeReturnOrder(certificateOrderDTO));
    }

    /**
     * 审核退款
     *
     * @param certificateOrderDTO 订单id
     * @return
     */
    @PostMapping("/authReturnOrder")
    @ApiOperation(value = "审核退款")
    @SysLog("审核退款")
    public R<CertificateOrderVO> authReturnOrder(@RequestBody CertificateOrderDTO certificateOrderDTO) {
        return R.success(baseService.authReturnOrder(certificateOrderDTO.getId(), certificateOrderDTO.getReturnIsAuth()));
    }

    /**
     * 订单详情
     *
     * @param orderId 订单id
     * @return
     */
    @GetMapping("/detail")
    @ApiOperation(value = "订单详情")
    @SysLog("订单详情")
    @BaseControllerInfo(voGroup = CertificateOrderGroup.pageOrder.class)
    public R<CertificateOrderVO> detail(Long orderId) {
        return R.success(baseService.detail(orderId));
    }


    /**
     * 订单详情
     *
     * @param orderNumber 订单id
     * @return
     */
    @GetMapping("/detailOfNumber")
    @ApiOperation(value = "订单详情")
    @SysLog("订单详情")
    @BaseControllerInfo(voGroup = CertificateOrderGroup.pageOrder.class)
    public R<CertificateOrderVO> detailOfNumber(String orderNumber) {
        CertificateOrderDTO certificateOrderDTO = new CertificateOrderDTO();
        certificateOrderDTO.setOrderNumber(orderNumber);
        List<CertificateOrder> certificateOrderList = baseService.list(certificateOrderDTO, null);
        if (CollectionUtil.isNotEmpty(certificateOrderList)) {
            return R.success(baseService.detail(certificateOrderList.get(0).getId()));
        }
        return R.success(null);
    }


    /**
     * 补证
     *
     * @param certificateUserDTO 保存参数
     * @return 实体
     */
    @ApiOperation(value = "补证")
    @PostMapping("/makeCertificate")
    @SysLog("补证")
    public R<Boolean> makeCertificate(@RequestBody CertificateUserDTO certificateUserDTO) {
        return R.success(baseService.makeCertificate(certificateUserDTO));
    }


    /**
     * 开票
     *
     * @param takeApplyerDTO 保存参数
     * @return 实体
     */
    @ApiOperation(value = "开票")
    @PostMapping("/takeRate")
    @SysLog("开票")
    public R<Boolean> takeRate(@RequestBody TakeApplyerDTO takeApplyerDTO) {

        return R.success(baseService.takeRate(takeApplyerDTO));
    }


    /**
     * 打印小票信息
     *
     * @return
     */
    @PostMapping("getNodeData")
    @BaseControllerInfo()
    public R<CertificatesOrderNodeVo> getNodeData(@RequestBody CertificateOrderDTO certificateOrderDTO) {
        CertificateOrder certificateOrder = baseService.getByIdCache(certificateOrderDTO.getId());
        if (BusinessConstant.YES != certificateOrder.getIsPay()) {
            throw BizException.wrap(CertificateExceptionCode.ORDER_PAY_NO);
        }
        CertificatesOrderNodeVo certificatesOrderNodeVo = new CertificatesOrderNodeVo();
        CertificateUserDTO certificateUserDTO = new CertificateUserDTO();
        certificateUserDTO.setOrderId(certificateOrderDTO.getId());
        List<CertificateUser> certificateUserList = certificateUserService.list(certificateUserDTO, null);
        certificatesOrderNodeVo.setOrderNumber(certificateOrder.getOrderNumber());
        certificatesOrderNodeVo.setOrderAmount(certificateOrder.getCostMoney());
        certificatesOrderNodeVo.setCarTotal(certificateUserList.size());
        certificatesOrderNodeVo.setTotalAmount(ObjectUtil.isEmpty(certificateOrder.getOverTimeMoney()) ? certificateOrder.getCostMoney() : certificateOrder.getCostMoney().add(certificateOrder.getOverTimeMoney()));

        //查询服务商信息
        ServiceProviderDTO query = new ServiceProviderDTO();
        query.setIds(Arrays.asList(certificateUserList.get(0).getCompanyId()));
        R<List<ServiceProviderVO>> serviceProviderListR = serviceProviderFeign.queryServiceProvider(query);
        if (serviceProviderListR.getIsSuccess() && serviceProviderListR.getData() != null && !serviceProviderListR.getData().isEmpty()) {
            for (ServiceProviderVO serviceProviderVO : serviceProviderListR.getData()) {
                certificatesOrderNodeVo.setCompanyName(serviceProviderVO.getCompanyName());
            }
        }

        BigDecimal bigDecimal = new BigDecimal(0);
        certificatesOrderNodeVo.setTotalDeposit(bigDecimal);
        /**
         * 人证 子信息
         */
        List<PeopleNodeVO> peopleNodeVOList = new ArrayList<>();
        /**
         * 车证 子信息
         */
        List<CarNodeVO> carNodeVOList = new ArrayList<>();
        if (CertificateUserCertificateTypeEnum.PEOPLE.equals(certificateUserList.get(0).getCertificateType())) {
            //人证
            for (CertificateUser certificateUser : certificateUserList) {
                Certificate certificate = certificateService.getByIdCache(certificateUser.getCertificateId());
                PeopleNodeVO peopleNodeVO = new PeopleNodeVO();
                peopleNodeVO.setAmount(certificate.getCostMoney());
                peopleNodeVO.setDeposit(certificate.getDepositMoney());
                peopleNodeVO.setName(certificateUser.getFullName());
                peopleNodeVO.setPrice(certificate.getCostMoney());
                peopleNodeVO.setSum(1);
                peopleNodeVOList.add(peopleNodeVO);
            }
            certificatesOrderNodeVo.setPeopleNodeVOList(peopleNodeVOList);
        } else if (CertificateUserCertificateTypeEnum.CAR.equals(certificateUserList.get(0).getCertificateType())) {
            //车证
            for (CertificateUser certificateUser : certificateUserList) {
                Certificate certificate = certificateService.getByIdCache(certificateUser.getCertificateId());
                CarNodeVO carNodeVO = new CarNodeVO();
                carNodeVO.setAmount(certificate.getCostMoney());
                carNodeVO.setDeposit(certificate.getDepositMoney());
                carNodeVO.setLicensePlateNumber(certificateUser.getCarNumber());
                carNodeVO.setPrice(certificate.getCostMoney());
                carNodeVO.setSum(1);
                carNodeVOList.add(carNodeVO);
            }
            certificatesOrderNodeVo.setCarNodeVOList(carNodeVOList);
        }
        return R.success(certificatesOrderNodeVo);
    }

    /**
     * 确认打印小票
     *
     * @return
     */
    @PostMapping("confirmPrintNode")
    @SysLog("确认打印小票")
    public R confirmPrintNode(@RequestBody CertificateOrderDTO certificateOrderDTO) {
        CertificateOrder certificateOrder = baseService.getByIdCache(certificateOrderDTO.getId());
        if (BusinessConstant.YES != certificateOrder.getIsPay()) {
            throw BizException.wrap(CertificateExceptionCode.ORDER_PAY_NO);
        }
        certificateOrder.setIsPrintTakeNode(BusinessConstant.YES);
        baseService.updateById(certificateOrder);
        return R.success(certificateOrder);
    }


    /**
     * 确认打印证件
     *
     * @return
     */
    @PostMapping("confirmPrint")

    public R confirmPrint(@RequestBody CertificateOrderDTO certificateOrderDTO) {

        Boolean isPrintTake = true;
        if (!CollectionUtil.isEmpty(certificateOrderDTO.getCertificateUserIdList())) {
            CertificateUserDTO certificateUserDTO = new CertificateUserDTO();
            certificateUserDTO.setOrderId(certificateOrderDTO.getId());
            List<CertificateUser> certificateUserList = certificateUserService.list(certificateUserDTO, null);
            if (CollectionUtil.isEmpty(certificateUserList)) {
                return R.fail("找不到订单");
            }
            for (CertificateUser certificateUser : certificateUserList) {
                if (certificateOrderDTO.getCertificateUserIdList().contains(certificateUser.getId())) {
                    certificateUser.setIsPrintTake(BusinessConstant.YES);
                    certificateUser.setCertificateStatus(CertificateUserCertificateStatusEnum.PRINT);
                    certificateUserService.updateById(certificateUser);
                }
            }

            for (CertificateUser certificateUser : certificateUserList) {
                if (ObjectUtil.isNotEmpty(certificateUser.getIsPrintTake()) && BusinessConstant.YES != certificateUser.getIsPrintTake()) {
                    isPrintTake = false;
                }
            }
            if (isPrintTake) {
                CertificateOrder certificateOrder = baseService.getByIdCache(certificateUserList.get(0).getOrderId());
                if (certificateOrder != null) {
                    certificateOrder.setIsPrintTake(BusinessConstant.YES);
                    baseService.updateById(certificateOrder);
                }
            }
        }
        return R.success();
    }


    /**
     * 更新业务状态
     *
     * @param certificateOrderDTO 保存参数
     * @return 实体
     */
    @ApiOperation(value = "更新业务状态")
    @PostMapping("/updateCertificateStatus")
    public R<CertificateOrder> updateCertificateStatus(@RequestBody CertificateOrderDTO certificateOrderDTO) {
        CertificateOrder certificateOrder = baseService.getByIdCache(certificateOrderDTO.getId());
        if (certificateOrder != null) {
            BeanUtils.copyProperties(certificateOrderDTO, certificateOrder);
            baseService.updateById(certificateOrder);
        }
        return R.success(certificateOrder);
    }


}
